package com.hitqz.robot.netty.handler;

import com.google.common.util.concurrent.RateLimiter;
import com.hitqz.robot.router.ChipMessageRouter;
import com.hitqz.robot.camera.communication.NetworkServiceThreadPool;
import com.hitqz.robot.netty.message.ChipMessage;
import com.hitqz.robot.strategy.ChipMessageHandlerStrategy;
import com.hitqz.robot.util.ChipToolKit;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.net.InetSocketAddress;

/**
 * @author xupkun
 * @date 2023/8/7
 */
@Slf4j
@Component
public class HitChipMessageHandler extends ChannelInboundHandlerAdapter {
    private static final RateLimiter logLimiter = RateLimiter.create(1);

    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        super.channelUnregistered(ctx);
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        // 当连接建立时的处理逻辑
        log.info("[track]channel connection active: {}", ctx.channel().remoteAddress());

        InetSocketAddress ipSocket = (InetSocketAddress)ctx.channel().remoteAddress();
        String ipAddress = ipSocket.getAddress().getHostAddress();
        ChipToolKit.addChannel(ipAddress, ctx);
        super.channelActive(ctx);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof ChipMessage message) {
            // 在这里处理消息，比如解析内容、处理业务逻辑等
            handleMessage(ctx, message);
        } else {
            log.warn("[track]channel read unknown message type: {}", msg.getClass().getName());
        }
    }

    // 处理消息的业务逻辑
    private void handleMessage(ChannelHandlerContext ctx, ChipMessage message) {
        // 根据命令进行分发
        NetworkServiceThreadPool.dealMessage(() -> {
            //异步分发给不同的 handler 用到反射,handler主线程不要做耗时间的操作,否则会阻塞线程
            byte[] data = message.getData();
            byte mainCmd = data[0];
            ChipMessageHandlerStrategy strategy = ChipMessageRouter.getHandlerStrategy(mainCmd);
            if (strategy == null) {
                this.simpleHandle(ctx, message);
            }else {
                strategy.handle(ctx, message);
            }
        });
    }


    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        InetSocketAddress ipSocket = (InetSocketAddress)ctx.channel().remoteAddress();
        String ipAddress = ipSocket.getAddress().getHostAddress();
        ChipToolKit.removeChannel(ipAddress, ctx);
        super.userEventTriggered(ctx, evt);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {

        InetSocketAddress ipSocket = (InetSocketAddress)ctx.channel().remoteAddress();
        String ipAddress = ipSocket.getAddress().getHostAddress();
        ChipToolKit.removeChannel(ipAddress, ctx);
        super.exceptionCaught(ctx, cause);
    }


    /**
     * 简单处理一些没有子命令的消息
     *
     * @param ctx
     * @param message
     */
    private void simpleHandle(ChannelHandlerContext ctx, ChipMessage message) {

    }


}
